package com.jfzt.service.impl;

import com.jfzt.common.IndexConstant;
import com.jfzt.common.ResultDocument;
import com.jfzt.common.ResultMapping;
import com.jfzt.pojo.QueryParamDto;
import com.jfzt.service.IElasticService;
import com.jfzt.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: shunpeng.hu
 * @date: 2024/1/22 12:09
 */
@Slf4j
@Service
public class ElasticServiceImpl implements IElasticService {

    @Autowired
    private RestHighLevelClient client;

    private static RestHighLevelClient restHighLevelClient;

    @PostConstruct
    public void elasticsearchServiceImpl() {
        restHighLevelClient = this.client;
    }

    @Override
    public ResultMapping queryMatchAll(QueryParamDto queryParamDto) {
        try {
            Integer currentPage = queryParamDto.getCurrentPage();
            Integer pageSize = queryParamDto.getPageSize();
            int start = (currentPage - 1) * pageSize;
            // 创建搜索请求对象
            SearchRequest request = new SearchRequest();
            // 查询的请求体
            SearchSourceBuilder builder = new SearchSourceBuilder()
                    .query(QueryBuilders.matchAllQuery())
                    .from(start)
                    .size(pageSize);
//            String[] excludes = {"kcAdmin", "kcRealm"};
//            String[] includes = {};
//            builder.fetchSource(queryParamDto.getIncludes(), queryParamDto.getExcludes());
            request.indices(queryParamDto.getIndexName()).source(builder);
            // 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);

            // 解析响应结果
            return handlerResponse(response);
        } catch (IOException e) {
            log.error("error");
        }
        return ResultMapping.success();
    }

    @Override
    public ResultMapping queryMatchFeild(QueryParamDto queryParamDto) {
        try {
            Integer currentPage = queryParamDto.getCurrentPage();
            Integer pageSize = queryParamDto.getPageSize();
            int start = (currentPage - 1) * pageSize;
            // 创建搜索请求对象
            SearchRequest request = new SearchRequest();
            // 查询的请求体
            SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.boolQuery()
                            .should(QueryBuilders.matchAllQuery())
                            .should(QueryBuilders.matchQuery(queryParamDto.getQueryKey()[0], queryParamDto.getKcAdmin())))
                    .from(start)
                    .size(pageSize);
            request.indices(queryParamDto.getIndexName()).source(builder);
            // 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 解析响应结果
            return handlerResponse(response);
        } catch (IOException e) {
            log.error("error");
        }
        return ResultMapping.success();
    }

    @Override
    public ResultMapping queryMulitMatchByFeild(QueryParamDto queryParamDto) {
        try {
            Integer currentPage = queryParamDto.getCurrentPage();
            Integer pageSize = queryParamDto.getPageSize();
            int start = (currentPage - 1) * pageSize;
            // 创建搜索请求对象
            SearchRequest request = new SearchRequest();
            // 查询的请求体
            SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.boolQuery()
                    .should(QueryBuilders.multiMatchQuery("kcAdmin", queryParamDto.getQueryKey())));

            request.indices(queryParamDto.getIndexName()).source(builder);
            // 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 解析响应结果
            return handlerResponse(response);
        } catch (IOException e) {
            log.error("error");
        }
        return ResultMapping.success();
    }

    @Override
    public String quaryAll() {
        try {
            // 创建搜索请求对象
            SearchRequest request = new SearchRequest();

            // 查询的请求体
            SearchSourceBuilder builder = new SearchSourceBuilder()
                    .query(QueryBuilders.matchAllQuery())
                    .trackTotalHits(true);

            //发送请求
            request.indices(IndexConstant.LOGINV2_INDEX).source(builder);

            // 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 解析响应结果
            return null;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void createLoginIndex(String indexName) {
        try {

            // 创建Request对象
            CreateIndexRequest request = new CreateIndexRequest(indexName);

            //发送请求
            restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new ElasticsearchStatusException("创建索引库异常~", RestStatus.fromCode(500), e.getMessage());
        }
    }

    @Override
    public void deleteLoginIndex(String indexName) {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(indexName);
            restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void createLoginDocument(String indexName, Map<String, Object> document) {
        try {
            SearchRequest searchRequest = new SearchRequest(IndexConstant.ES_INDEX_CONSTANT);

            searchRequest.source().query(QueryBuilders.matchAllQuery()).trackTotalHits(true);
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            long value = response.getHits().getTotalHits().value;
            long _id = (value == 0) ? value = 1 : value + 1;

            //创建Request对象
            IndexRequest indexRequest = new IndexRequest(IndexConstant.ES_INDEX_CONSTANT).id(String.valueOf(_id)).source(document);

            //发送请求
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new ElasticsearchStatusException("创建登录索引文档异常~", RestStatus.fromCode(500), e.getMessage());
        }
    }

    @Override
    public String queryLoginIndex(String indexName) {
        try {
            GetIndexRequest request = new GetIndexRequest(indexName);
            restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return "查询成功";
    }


    private ResultMapping handlerResponse(SearchResponse response) {
        //获取总条数
        long totalValue = response.getHits().getTotalHits().value;
        // 文档数组
        Map<String, ResultDocument> documents = new HashMap<>();
        for (SearchHit hit : response.getHits().getHits()) {
            String json = hit.getSourceAsString();
            documents.put("data", JsonUtils.jsonStringToObject(json, ResultDocument.class));
        }
        return ResultMapping.success(totalValue, documents);
    }
}
